Expand description
Rust bindings for libffi.
The C libffi library provides two main facilities: assembling calls
to functions dynamically, and creating closures that can be called
as ordinary C functions. In Rust, the latter means that we can turn
a Rust lambda (or any object implementing Fn
/FnMut
) into an
ordinary C function pointer that we can pass as a callback to C.
The easiest way to use this library is via the
high
layer module, but more flexibility (and
less checking) is provided by the middle
and
low
layers.
Usage
Building libffi will build lifbffi-sys, which will in turn build the libffi C library from github, which requires that you have a working make, C compiler, automake, and autoconf first. It’s on crates.io, so you can add
[dependencies]
libffi = "3.2.0"
This crate depends on the libffi-sys
crate, which by default
attempts to build its own version of the C libffi library. In order to
use your system’s C libffi instead, enable this crate’s system
feature in your Cargo.toml
:
[features]
libffi = { version = "3.2.0", features = ["system"] }
See the libffi-sys
documentation for more information about how it
finds C libffi.
This crate supports Rust version 1.48 and later.
Organization
This library is organized in four layers, each of which attempts to provide more safety and a simpler interface than the next layer down. From top to bottom:
- The
high
layer provides safe(?) and automatic marshalling of Rust closures into C function pointers. - The
middle
layer provides memory-managed abstractions for assembling calls and closures, but is unsafe because it doesn’t check argument types. - The
low
layer makes no attempts at safety, but provides a more idiomatically “Rusty” API than the underlying C library. - The
raw
layer is a re-export of thelibffi-sys
crate, a direct mapping of the C libffi library into Rust, generated by bindgen.
It should be possible to use any layer without dipping into lower layers (and it will be considered a bug to the extent that it isn’t).
Examples
In this example, we convert a Rust lambda containing a free variable
into an ordinary C code pointer. The type of fun
below is
extern "C" fn(u64, u64) -> u64
.
use libffi::high::Closure2;
let x = 5u64;
let f = |y: u64, z: u64| x + y + z;
let closure = Closure2::new(&f);
let fun = closure.code_ptr();
assert_eq!(18, fun.call(6, 7));
Modules
- High layer providing automatic marshalling of Rust closures as C function pointers.
- A low-level wrapping of libffi, this layer makes no attempts at safety, but tries to provide a somewhat more idiomatic interface.
- Middle layer providing a somewhat safer (but still quite unsafe) API.
- Raw definitions imported from the C library (via bindgen).
Macros
- Performs a dynamic call to a C function.